home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / tex / webtp55.arc / WEAVE.CHG < prev    next >
Text File  |  1989-12-01  |  26KB  |  793 lines

  1. % This is WEAVE.CHG for TURBO Pascal 5.5
  2. % (c) 1989 by Peter Sawatzki
  3. %
  4. %  Change History:
  5. %
  6. %  Initials:   PS = Peter Sawatzki, FE617@DHAFEU11
  7. %  =========
  8. %
  9. %  rel.  date      Author  description
  10. %  ====  ====      ======  ===========
  11. %  v0.1  5-Mar-88  PS      initial TP3 release
  12. %  v0.2 29-Jul-89  PS      @i option: (nested) include files
  13. %
  14. %
  15. %  Tangle/Compile Instructions:
  16. %  ============================
  17. %  TANGLE WEAVE /d /m /c
  18. %  TPC /$A+,O-,E-,N-,B-,I-,V-,S-,D- /$M$5000,0,$2000 WEAVE
  19. %
  20. %
  21. ────────────────────────────────────────────────────────────────
  22. @x l.72 m.1
  23. @d banner=='This is WEAVE, Version 4'
  24. @y
  25. @d banner=='This is WEAVE, Version 4/TP55 0.2'
  26. @z
  27. ────────────────────────────────────────────────────────────────
  28. @x l.82 m.2
  29. @d end_of_WEAVE = 9999 {go here to wrap it up}
  30.  
  31. @p @t\4@>@<Compiler directives@>@/
  32. program WEAVE(@!web_file,@!change_file,@!tex_file);
  33. label end_of_WEAVE; {go here to finish}
  34. const @<Constants in the outer block@>@/
  35. type @<Types in the outer block@>@/
  36. var @<Globals in the outer block@>@/
  37. @y
  38. @p program WEAVE;
  39. const @<Constants in the outer block@>@/
  40. type @<Types in the outer block@>@/
  41. const @<Typed constants in the outer block@>@/
  42. var @<Globals in the outer block@>@/
  43. @<Inline procedures and functions@>@/
  44. @<All purpose procedures and functions@>@/
  45. @z
  46. ────────────────────────────────────────────────────────────────
  47. @x l.101 m.3
  48. @d debug==@{ {change this to `$\\{debug}\equiv\null$' when debugging}
  49. @d gubed==@t@>@} {change this to `$\\{gubed}\equiv\null$' when debugging}
  50. @y
  51. @d ifdef(#)==@={$ifdef @>#@=}@>
  52. @d endif==@={$endif}@>
  53. @d debug==ifdef(deb)
  54. @d gubed==endif
  55. @d Asm(#)==inline(@[#@])
  56. @z
  57. ────────────────────────────────────────────────────────────────
  58. @x l.106 m.3
  59. @d stat==@{ {change this to `$\\{stat}\equiv\null$'
  60.   when gathering usage statistics}
  61. @d tats==@t@>@} {change this to `$\\{tats}\equiv\null$'
  62.   when gathering usage statistics}
  63. @y
  64. @d stat==ifdef(sta)
  65. @d tats==endif
  66. @z
  67. ────────────────────────────────────────────────────────────────
  68. @x l.121 m.4
  69. @<Compiler directives@>=
  70. @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead}
  71. @!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging}
  72. @y
  73. @<Inline proc...@>=
  74. function mavail: word;
  75. Asm(mov ah,$48/   {allocate memory}
  76.     mov bx,$FFFF/ {determine free memory}
  77.     int $21/
  78.     mov ax,bx);   {return size of largest available block}
  79.  
  80. function malloc (no: word): word;
  81. Asm(mov ah,$48/   {allocate memory}
  82.     pop bx/       {no of bytes}
  83.     int $21/
  84.     jnc ok/       {no error}
  85.     xor ax,ax/    {clear ax in case of error}
  86.  ok: );
  87.  
  88. procedure mfree (segm: word);
  89. Asm(mov ah,$49/ {free memory}
  90.     pop es/     {segment to free}
  91.     int $21);
  92. @z
  93. ────────────────────────────────────────────────────────────────
  94. @x l.146 m.6
  95. @d incr(#) == #:=#+1 {increase a variable by unity}
  96. @d decr(#) == #:=#-1 {decrease a variable by unity}
  97. @y
  98. @d incr(#) == Inc(#) {increase a variable by unity}
  99. @d decr(#) == Dec(#) {decrease a variable by unity}
  100. @d integer == LongInt
  101. @d void == begin end
  102. @z
  103. ────────────────────────────────────────────────────────────────
  104. @x l.172 m.7
  105. @d othercases == others: {default for cases not listed explicitly}
  106. @y
  107. @d othercases == else {default for cases not listed explicitly}
  108. @z
  109. ────────────────────────────────────────────────────────────────
  110. @x l.181 m.8
  111. @!max_bytes=45000; {|1/ww| times the number of bytes in identifiers,
  112.   index entries, and module names; must be less than 65536}
  113. @!max_names=5000; {number of identifiers, index entries, and module names;
  114.   must be less than 10240}
  115. @!max_modules=2000;{greater than the total number of modules}
  116. @!hash_size=353; {should be prime}
  117. @!buf_size=100; {maximum length of input line}
  118. @!longest_name=400; {module names shouldn't be longer than this}
  119. @!long_buf_size=500; {|buf_size+longest_name|}
  120. @!line_length=80; {lines of \TeX\ output have at most this many characters,
  121.   should be less than 256}
  122. @!max_refs=30000; {number of cross references; must be less than 65536}
  123. @!max_toks=30000; {number of symbols in \PASCAL\ texts being parsed;
  124.   must be less than 65536}
  125. @!max_texts=2000; {number of phrases in \PASCAL\ texts being parsed;
  126.   must be less than 10240}
  127. @!max_scraps=1000; {number of tokens in \PASCAL\ texts being parsed}
  128. @!stack_size=200; {number of simultaneous output levels}
  129. @y
  130. @!max_bytes=6400; {|1/ww| times the number of bytes in identifiers,
  131.   index entries, and module names; must be less than 65536}
  132. @!max_names=5000; {number of identifiers, index entries, and module names;
  133.   must be less than 10240}
  134. @!max_modules=2000;{greater than the total number of modules}
  135. @!hash_size=353; {should be prime}
  136. @!buf_size=100; {maximum length of input line}
  137. @!longest_name=400; {module names shouldn't be longer than this}
  138. @!long_buf_size=500; {|buf_size+longest_name|}
  139. @!line_length=80; {lines of \TeX\ output have at most this many characters,
  140.   should be less than 256}
  141. @!max_refs=32000; {number of cross references; must be less than 65536}
  142. @!max_toks=32000; {number of symbols in \PASCAL\ texts being parsed;
  143.   must be less than 65536}
  144. @!max_texts=3000; {number of phrases in \PASCAL\ texts being parsed;
  145.   must be less than 10240}
  146. @!max_scraps=3000; {number of tokens in \PASCAL\ texts being parsed}
  147. @!stack_size=300; {number of simultaneous output levels}
  148. @z
  149. ────────────────────────────────────────────────────────────────
  150. @x l.307 m.12
  151. @!text_file=packed file of text_char;
  152. @y
  153. @!text_file=Text;
  154. @z
  155. ────────────────────────────────────────────────────────────────
  156. @x l.309 m.13
  157. @ The \.{WEAVE} and \.{TANGLE} processors convert between ASCII code and
  158. the user's external character set by means of arrays |xord| and |xchr|
  159. that are analogous to \PASCAL's |ord| and |chr| functions.
  160.  
  161. @<Globals...@>=
  162. @!xord: array [text_char] of ASCII_code;
  163.   {specifies conversion of input characters}
  164. @!xchr: array [ASCII_code] of text_char;
  165.   {specifies conversion of output characters}
  166.  
  167. @ If we assume that every system using \.{WEB} is able to read and write the
  168. visible characters of standard ASCII (although not necessarily using the
  169. ASCII codes to represent them), the following assignment statements initialize
  170. most of the |xchr| array properly, without needing any system-dependent
  171. changes. For example, the statement \.{xchr[@@\'101]:=\'A\'} that appears
  172. in the present \.{WEB} file might be encoded in, say, {\mc EBCDIC} code
  173. on the external medium on which it resides, but \.{TANGLE} will convert from
  174. this external code to ASCII and back again. Therefore the assignment
  175. statement \.{XCHR[65]:=\'A\'} will appear in the corresponding \PASCAL\ file,
  176. and \PASCAL\ will compile this statement so that |xchr[65]| receives the
  177. character \.A in the external (|char|) code. Note that it would be quite
  178. incorrect to say \.{xchr[@@\'101]:="A"}, because |"A"| is a constant of
  179. type |integer|, not |char|, and because we have $|"A"|=65$ regardless of
  180. the external character set.
  181.  
  182. @<Set init...@>=
  183. xchr[@'40]:=' ';
  184. xchr[@'41]:='!';
  185. xchr[@'42]:='"';
  186. xchr[@'43]:='#';
  187. xchr[@'44]:='$';
  188. xchr[@'45]:='%';
  189. xchr[@'46]:='&';
  190. xchr[@'47]:='''';@/
  191. xchr[@'50]:='(';
  192. xchr[@'51]:=')';
  193. xchr[@'52]:='*';
  194. xchr[@'53]:='+';
  195. xchr[@'54]:=',';
  196. xchr[@'55]:='-';
  197. xchr[@'56]:='.';
  198. xchr[@'57]:='/';@/
  199. xchr[@'60]:='0';
  200. xchr[@'61]:='1';
  201. xchr[@'62]:='2';
  202. xchr[@'63]:='3';
  203. xchr[@'64]:='4';
  204. xchr[@'65]:='5';
  205. xchr[@'66]:='6';
  206. xchr[@'67]:='7';@/
  207. xchr[@'70]:='8';
  208. xchr[@'71]:='9';
  209. xchr[@'72]:=':';
  210. xchr[@'73]:=';';
  211. xchr[@'74]:='<';
  212. xchr[@'75]:='=';
  213. xchr[@'76]:='>';
  214. xchr[@'77]:='?';@/
  215. xchr[@'100]:='@@';
  216. xchr[@'101]:='A';
  217. xchr[@'102]:='B';
  218. xchr[@'103]:='C';
  219. xchr[@'104]:='D';
  220. xchr[@'105]:='E';
  221. xchr[@'106]:='F';
  222. xchr[@'107]:='G';@/
  223. xchr[@'110]:='H';
  224. xchr[@'111]:='I';
  225. xchr[@'112]:='J';
  226. xchr[@'113]:='K';
  227. xchr[@'114]:='L';
  228. xchr[@'115]:='M';
  229. xchr[@'116]:='N';
  230. xchr[@'117]:='O';@/
  231. xchr[@'120]:='P';
  232. xchr[@'121]:='Q';
  233. xchr[@'122]:='R';
  234. xchr[@'123]:='S';
  235. xchr[@'124]:='T';
  236. xchr[@'125]:='U';
  237. xchr[@'126]:='V';
  238. xchr[@'127]:='W';@/
  239. xchr[@'130]:='X';
  240. xchr[@'131]:='Y';
  241. xchr[@'132]:='Z';
  242. xchr[@'133]:='[';
  243. xchr[@'134]:='\';
  244. xchr[@'135]:=']';
  245. xchr[@'136]:='^';
  246. xchr[@'137]:='_';@/
  247. xchr[@'140]:='`';
  248. xchr[@'141]:='a';
  249. xchr[@'142]:='b';
  250. xchr[@'143]:='c';
  251. xchr[@'144]:='d';
  252. xchr[@'145]:='e';
  253. xchr[@'146]:='f';
  254. xchr[@'147]:='g';@/
  255. xchr[@'150]:='h';
  256. xchr[@'151]:='i';
  257. xchr[@'152]:='j';
  258. xchr[@'153]:='k';
  259. xchr[@'154]:='l';
  260. xchr[@'155]:='m';
  261. xchr[@'156]:='n';
  262. xchr[@'157]:='o';@/
  263. xchr[@'160]:='p';
  264. xchr[@'161]:='q';
  265. xchr[@'162]:='r';
  266. xchr[@'163]:='s';
  267. xchr[@'164]:='t';
  268. xchr[@'165]:='u';
  269. xchr[@'166]:='v';
  270. xchr[@'167]:='w';@/
  271. xchr[@'170]:='x';
  272. xchr[@'171]:='y';
  273. xchr[@'172]:='z';
  274. xchr[@'173]:='{';
  275. xchr[@'174]:='|';
  276. xchr[@'175]:='}';
  277. xchr[@'176]:='~';@/
  278. xchr[0]:=' '; xchr[@'177]:=' '; {these ASCII codes are not used}
  279. @y
  280. @ The \.{WEAVE} and \.{TANGLE} processors convert between ASCII code and
  281. the user's external character set by means of arrays |xord| and |xchr|
  282. that are analogous to \PASCAL's |ord| and |chr| functions.
  283. The following typed constants define the |xchr| array properly.
  284.  
  285. @<Typed constants...@>=
  286. xchr: array [ASCII_code] of text_char=(@/
  287. ' ',' ',' ',' ',' ',' ',' ',' ',  ' ', #9,' ',' ',' ',#13,' ',' ',@/
  288. ' ',' ',' ',' ',' ',' ',' ',' ',  ' ',' ',' ',' ',' ',' ',' ',' ',@/
  289. ' ','!','"','#','$','%','&','''', '(',')','*','+',',','-','.','/',@/
  290. '0','1','2','3','4','5','6','7',  '8','9',':',';','<','=','>','?',@/
  291. '@@','A','B','C','D','E','F','G', 'H','I','J','K','L','M','N','O',@/
  292. 'P','Q','R','S','T','U','V','W',  'X','Y','Z','[','\',']','^','_',@/
  293. '`','a','b','c','d','e','f','g',  'h','i','j','k','l','m','n','o',@/
  294. 'p','q','r','s','t','u','v','w',  'x','y','z','{','|','}','~',' ',@/
  295. ' ',' ',' ',' ',' ',' ',' ',' ',  ' ',' ',' ',' ',' ',' ',' ',' ',@/
  296. ' ',' ',' ',' ',' ',' ',' ',' ',  ' ',' ',' ',' ',' ',' ',' ',' ',@/
  297. ' ',' ',' ',' ',' ',' ',' ',' ',  ' ',' ',' ',' ',' ',' ',' ',' ',@/
  298. ' ',' ',' ',' ',' ',' ',' ',' ',  ' ',' ',' ',' ',' ',' ',' ',' ',@/
  299. ' ',' ',' ',' ',' ',' ',' ',' ',  ' ',' ',' ',' ',' ',' ',' ',' ',@/
  300. ' ',' ',' ',' ',' ',' ',' ',' ',  ' ',' ',' ',' ',' ',' ',' ',' ',@/
  301. ' ',' ',' ',' ',' ',' ',' ',' ',  ' ',' ',' ',' ',' ',' ',' ',' ',@/
  302. ' ',' ',' ',' ',' ',' ',' ',' ',  ' ',' ',' ',' ',' ',' ',' ',' ');
  303.  
  304. @ The following definition makes the |xord| array contain a
  305. suitable inverse to the information in |xchr|.
  306.  
  307. @<Globals...@>=
  308. @!xord: array [text_char] of ASCII_code absolute xchr;
  309.   {specifies conversion of input characters}
  310. @z
  311. ────────────────────────────────────────────────────────────────
  312. @x l.449 m.16
  313. @ When we initialize the |xord| array and the remaining parts of |xchr|,
  314. it will be convenient to make use of an index variable, |i|.
  315.  
  316. @<Local variables for init...@>=
  317. @!i:0..255;
  318.  
  319. @ Here now is the system-dependent part of the character set.
  320. If \.{WEB} is being implemented on a garden-variety \PASCAL\ for which
  321. only standard ASCII codes will appear in the input and output files, you
  322. don't need to make any changes here. But if you have, for example, an extended
  323. character set like the one in Appendix~C of {\sl The \TeX book}, the first
  324. line of code in this module should be changed to
  325. $$\hbox{|for i:=1 to @'37 do xchr[i]:=chr(i);|}$$
  326. \.{WEB}'s character set is essentially identical to \TeX's, even with respect to
  327. characters less than @'40.
  328. @^system dependencies@>
  329.  
  330. Changes to the present module will make \.{WEB} more friendly on computers
  331. that have an extended character set, so that one can type things like
  332. \.^^Z\ instead of \.{<>}. If you have an extended set of characters that
  333. are easily incorporated into text files, you can assign codes arbitrarily
  334. here, giving an |xchr| equivalent to whatever characters the users of
  335. \.{WEB} are allowed to have in their input files, provided that unsuitable
  336. characters do not correspond to special codes like |carriage_return|
  337. that are listed above.
  338.  
  339. (The present file \.{WEAVE.WEB} does not contain any of the non-ASCII
  340. characters, because it is intended to be used with all implementations of
  341. \.{WEB}.  It was originally created on a Stanford system that has a
  342. convenient extended character set, then ``sanitized'' by applying another
  343. program that transliterated all of the non-standard characters into
  344. standard equivalents.)
  345.  
  346. @<Set init...@>=
  347. for i:=1 to @'37 do xchr[i]:=' ';
  348. for i:=@'200 to @'377 do xchr[i]:=' ';
  349.  
  350. @ The following system-independent code makes the |xord| array contain a
  351. suitable inverse to the information in |xchr|.
  352.  
  353. @<Set init...@>=
  354. for i:=first_text_char to last_text_char do xord[chr(i)]:=" ";
  355. for i:=1 to @'377 do xord[xchr[i]]:=i;
  356. xord[' ']:=" ";
  357. @y
  358. @ not neccesssary
  359.  
  360. @ not neccessary
  361.  
  362. @ not neccessary
  363. @z
  364. ────────────────────────────────────────────────────────────────
  365. @x l.517 m.20
  366. @!term_out:text_file; {the terminal as an output file}
  367. @y
  368. @ @d term_out==Output
  369. @z
  370. ────────────────────────────────────────────────────────────────
  371. @x l.525 m.21
  372. rewrite(term_out,'TTY:'); {send |term_out| output to the terminal}
  373. @y
  374. @z
  375. ────────────────────────────────────────────────────────────────
  376. @x l.532 m.22
  377. @d update_terminal == break(term_out) {empty the terminal output buffer}
  378. @y
  379. @d update_terminal ==
  380. @z
  381. ────────────────────────────────────────────────────────────────
  382. @x l.534 m.23
  383. @ The main input comes from |web_file|; this input may be overridden
  384. by changes in |change_file|. (If |change_file| is empty, there are no changes.)
  385.  
  386. @<Globals...@>=
  387. @!web_file:text_file; {primary input}
  388. @!change_file:text_file; {updates}
  389. @y
  390. @ We need some data structures to implement the include facility of
  391.   \.{TANGLE}
  392. @<Constants...@>=
  393. No_of_Files = 5; {Webfile + Changefile + all Include files}
  394. buffer_size = 4*1024; {multiple of 16}
  395.  
  396. @ @<Globals...@>=
  397. FileMax: 0..No_of_Files; {how many files fit into memory}
  398. @!file_prev: array[1..No_of_Files] of word;
  399. @!file_ptr: array[1..No_of_Files] of word;
  400.  
  401. @ To access a textfile we use
  402. @d textf(#)==Text(Ptr(file_ptr[#],0)^)
  403.  
  404. @ The main input comes from |web_file|; this input may be overridden
  405. by changes in |change_file|. (If |change_file| is empty, there are no changes.)
  406.  
  407. @<Globals...@>=
  408. @!web_file:word; {primary input}
  409. @!change_file:word; {updates}
  410. @z
  411. ────────────────────────────────────────────────────────────────
  412. @x l.541 m.24
  413. @ The following code opens the input files.  Since these files were listed
  414. in the program header, we assume that the \PASCAL\ runtime system has
  415. already checked that suitable file names have been given; therefore no
  416. additional error checking needs to be done. We will see below that
  417. \.{WEAVE} reads through the entire input twice.
  418. @^system dependencies@>
  419.  
  420. @p procedure open_input; {prepare to read |web_file| and |change_file|}
  421. begin reset(web_file); reset(change_file);
  422. end;
  423. @y
  424. @ The following code closes an input file. If the input file is the son
  425. of another input file, the higher level file is returned.
  426. @^system dependencies@>
  427.  
  428. @p procedure close_fil (var f: word);
  429.      var tf: word;
  430.      begin
  431.        if f<>0 then begin
  432.          Close(textf(f));
  433.          if IoResult<>0 then void;
  434.          tf:= f;
  435.          f:= file_prev[f];
  436.          file_prev[tf]:= 0; { buffer now available }
  437.          if f=$FFFF then f:= 0;
  438.        end
  439.      end;
  440.  
  441. @ Next we need a function to open an input file. Checks will be
  442.   made to verify that there are not too many include files open.
  443.  
  444. @p function open_fil (var f: word; name: String): boolean;
  445.      var
  446.        tf: word;
  447.      begin
  448.        open_fil:= false;
  449.        tf:= 1;
  450.        while (tf<=FileMax) and (file_prev[tf]<>0) do
  451.          Inc(tf);
  452.        if tf>FileMax then
  453.          fatal_halt('@@i ',name,': no more than ',FileMax,' open files.');
  454.        assign(textf(tf),name);
  455.        SetTextBuf(textf(tf),Ptr(file_ptr[tf],128)^,buffer_size);
  456.        reset(textf(tf));
  457.        if IoResult=0 then begin
  458.          open_fil:= true;
  459.          if f=0 then f:= $FFFF;
  460.          file_prev[tf]:= f;
  461.          f:= tf
  462.        end
  463.      end;
  464.  
  465. @ @<Close all Files@>=
  466. while web_file>0 do close_fil(web_file);
  467. while change_file>0 do close_fil(change_file);
  468.  
  469. @ The following code initializes the input buffers
  470. @<Local variables for init...@>=
  471. tf: word;
  472.  
  473. @ @<Set init...@>=
  474.   FileMax:= No_of_Files;
  475.   repeat
  476.     file_ptr[1]:= malloc(((buffer_size+128) shr 4) *FileMax);
  477.     if file_ptr[1]=0 then decr(FileMax)
  478.   until (file_ptr[1]<>0) or (FileMax<2);
  479.   if file_ptr[1]=0 then
  480.     fatal_halt('No memory for the webfile and a changefile.');
  481.   tf:= 2;
  482.   while tf<=No_of_Files do begin
  483.     file_ptr[tf]:= file_ptr[tf-1]+(buffer_size+128) shr 4;
  484.     incr(tf)
  485.   end;
  486.  
  487. @ We need a procedure to force the extension in a filename.
  488. @<Inline proc...@>=
  489.    function ForceExtension (FName, FExt : String): String;
  490.    {-Return a pathname with the specified extension attached}
  491.    var
  492.      i,DotPos,BackSlashPos: byte;
  493.    begin
  494.      DotPos := 0;
  495.      for i := 1 to _Length(FName) do begin
  496.        if FName[I]='.' then DotPos := i;
  497.        if FName[i]='\' then BackSlashPos:= i;
  498.      end;
  499.      if DotPos>BackSlashPos then
  500.        ForceExtension:= _copy(FName,1,DotPos)+FExt
  501.      else
  502.        ForceExtension := FName+'.'+FExt;
  503.    end;
  504.  
  505. @ Now we open the |web_file| and a |change_file| if present.
  506. @p procedure open_input; {prepare to read |web_file| and |change_file|}
  507. var
  508.   fn: String;
  509.   tf: word;
  510. begin
  511.   for tf:= 1 to No_of_Files do
  512.     file_prev[tf]:= 0;
  513.   web_file:= 0;
  514.   change_file:= 0;
  515.   if not open_fil(web_file,Parameter(1)) then
  516.     if not open_fil(web_file,ForceExtension(Parameter(1),'WEB')) then
  517.       fatal_halt('WEB file not found');
  518.   fn:= Parameter(2); if fn='' then fn:= Parameter(1);
  519.   if not open_fil(change_file,fn) then
  520.     if not open_fil(change_file,ForceExtension(fn,'CHG')) then
  521.       void;
  522. end;
  523. @z
  524. ────────────────────────────────────────────────────────────────
  525. @x l.554 m.25
  526. @<Globals...@>=
  527. @!tex_file: text_file;
  528. @y
  529. @<Globals...@>=
  530. @!tex_file: text_file;
  531. @!tex_buffer: word;
  532. @z
  533. ────────────────────────────────────────────────────────────────
  534. @x l.563 m.26
  535. @<Set init...@>=
  536. rewrite(tex_file);
  537. @y
  538. @<Close all...@>=
  539. @!Close(tex_file);
  540. @
  541. @<Set init...@>=
  542. tex_buffer:= malloc(8192 shr 4);
  543. assign(tex_file,ForceExtension(ParamStr(1),'TEX'));
  544. SetTextBuf(tex_file,Ptr(tex_buffer,0)^,8192);
  545. rewrite(tex_file);
  546. if IoResult>0 then fatal_halt('Unable to create ',ForceExtension(ParamStr(1),'TEX'));
  547. @z
  548. ────────────────────────────────────────────────────────────────
  549. @x l.586 m.28
  550. @p function input_ln(var f:text_file):boolean;
  551.   {inputs a line or returns |false|}
  552. var final_limit:0..buf_size; {|limit| without trailing blanks}
  553. begin limit:=0; final_limit:=0;
  554. if eof(f) then input_ln:=false
  555. else  begin while not eoln(f) do
  556.     begin buffer[limit]:=xord[f^]; get(f);
  557.     incr(limit);
  558.     if buffer[limit-1]<>" " then final_limit:=limit;
  559.     if limit=buf_size then
  560.       begin while not eoln(f) do get(f);
  561.       decr(limit); {keep |buffer[buf_size]| empty}
  562.       if final_limit>limit then final_limit:=limit;
  563.       print_nl('! Input line too long'); loc:=0; error;
  564. @.Input line too long@>
  565.       end;
  566.     end;
  567.   read_ln(f); limit:=final_limit; input_ln:=true;
  568.   end;
  569. end;
  570. @y
  571. @p function input_ln (var f: word):boolean;
  572.  label
  573.    new_file;
  574.  var
  575.    s: String;
  576.    fileend: boolean;
  577.    i: byte;
  578.  
  579.      procedure open_include;
  580.      var
  581.        i: byte;
  582.        fn: String;
  583.      begin
  584.        i:= 4;
  585.        while (i<=Length(s)) and (s[i]<>' ') do incr(i);
  586.        byte(fn[0]):= i-4;
  587.        move(s[4],fn[1],Length(fn));
  588.        if not open_fil(f,fn) then
  589.          if not open_fil(f,fn+'.CHI') then
  590.            if not open_fil(f,fn+'.CHG') then
  591.              fatal_halt('@@i ',fn,': Include file not found.')
  592.      end;
  593.  
  594.  begin new_file:
  595.    limit:= 0;
  596.    fileend:= eof(textf(f));
  597.    if IoResult>0 then fileend:= true;
  598.    if fileend then begin
  599.      close_fil(f);
  600.      if f>0 then
  601.        goto new_file
  602.      else
  603.        input_ln:= false
  604.    end else begin
  605.      readln(textf(f),s);
  606.      limit:= byte(s[0]);
  607.      if (limit>3) and (s[1]='@@') and (s[2]='i') and (s[3]=' ') then begin
  608.        open_include;
  609.        goto new_file
  610.      end;
  611.      while (limit>0) and (s[limit]=' ') do decr(limit);
  612.      for i:= 1 to limit do buffer[i-1]:= xord[s[i]];
  613.      input_ln:=true;
  614.    end;
  615.  end;
  616. @z
  617. ────────────────────────────────────────────────────────────────
  618. @x l.684 m.33
  619. @d fatal_error(#)==begin new_line; print(#); error; mark_fatal; jump_out;
  620.   end
  621.  
  622. @<Error handling...@>=
  623. procedure jump_out;
  624. begin goto end_of_WEAVE;
  625. end;
  626. @y
  627. @d fatal_error(#)==begin new_line; print(#); error; mark_fatal; Halt(history) end
  628. @d fatal_halt(#)==begin new_line; print(#); mark_fatal; Halt(history) end
  629. @z
  630. ────────────────────────────────────────────────────────────────
  631. @x l.729 m.37
  632. @d ww=2 {we multiply the byte capacity by approximately this amount}
  633. @y
  634. @d ww=16
  635. @z
  636. ────────────────────────────────────────────────────────────────
  637. @x l.731 m.37
  638. @<Globals...@>=
  639. @!byte_mem: packed array [0..ww-1,0..max_bytes] of ASCII_code;
  640.   {characters of names}
  641. @y
  642. @ @<Set init...@>=
  643. if (ww<>16) then
  644.   fatal_halt('! ww must be 16 (segment size).');
  645. byte_seg:= malloc(max_bytes+1);
  646. @ @<Inline...@>=
  647.   function bytem (s,o: word): Pointer;@/
  648.   Asm(pop dx/
  649.       pop ax/
  650.       add dx,[>byte_seg]);
  651. @ @d byte_mem[#]==ASCII_code(bytem(#)^)
  652. @ @<Globals...@>=
  653. @t\hskip1em@>@!byte_seg: word;
  654. @z
  655. ────────────────────────────────────────────────────────────────
  656. @x l.737 m.37
  657. @!xref: array [0..max_names] of sixteen_bits; {heads of cross-reference lists}
  658. @y
  659. @ @<Set init...@>=
  660. xref_base:= Ptr(malloc(sizeof(xref_ar) shr 4 +1),0);
  661. @ @d xref==xref_base^
  662. @ @<Types...@>=
  663. @!xref_ar= array [0..max_names] of sixteen_bits; {heads of cross-reference lists}
  664. @ @<Globals...@>=
  665. @t\hskip1em@>@!xref_base: ^xref_ar;
  666. @z
  667. ────────────────────────────────────────────────────────────────
  668. @x l.883 m.46
  669. @d num(#)==xmem[#].num_field
  670. @d xlink(#)==xmem[#].xlink_field
  671. @y
  672. @d num(#)==xm_num_field^[#]
  673. @d xlink(#)==xm_link_field^[#]
  674. @z
  675. ────────────────────────────────────────────────────────────────
  676. @x l.890 m.48
  677. @ @<Globals...@>=
  678. @!xmem:array[xref_number] of packed record@t@>@/
  679.   @!num_field: sixteen_bits; {module number plus zero or |def_flag|}
  680.   @!xlink_field: sixteen_bits; {pointer to the previous cross reference}
  681.   end;
  682. @y
  683. @ @<Set init...@>=
  684. xm_link_field:= Ptr(malloc(sizeof(xmem_ar) shr 4 +1),0);
  685. xm_num_field := Ptr(malloc(sizeof(xmem_ar) shr 4 +1),0);
  686. @ @<Types...@>=
  687. @!xmem_ar=array[xref_number] of sixteen_bits;
  688. @ @<Globals...@>=
  689. @!xm_link_field: ^xmem_ar;
  690. @!xm_num_field: ^xmem_ar;
  691. @z
  692. ────────────────────────────────────────────────────────────────
  693. @x l.965 m.53
  694. @t\hskip1em@>@!tok_mem: packed array [0..max_toks] of sixteen_bits; {tokens}
  695. @y
  696. @ @<Set init...@>=
  697. tok_base:= Ptr(malloc(sizeof(tok_ar) shr 4 +1),0);
  698. @ @d tok_mem==tok_base^
  699. @ @<Types...@>=
  700. @!tok_ar= array [0..max_toks] of sixteen_bits; {tokens}
  701. @ @<Globals...@>=
  702. @t\hskip1em@>@!tok_base: ^tok_ar;
  703. @z
  704. ────────────────────────────────────────────────────────────────
  705. @x l.1711 m.97
  706. @d up_to(#)==#-24,#-23,#-22,#-21,#-20,#-19,#-18,#-17,#-16,#-15,#-14,
  707.   #-13,#-12,#-11,#-10,#-9,#-8,#-7,#-6,#-5,#-4,#-3,#-2,#-1,#
  708. @y
  709. @z
  710. ────────────────────────────────────────────────────────────────
  711. @x l.1729 m.97
  712. "A",up_to("Z"),"a",up_to("z"): @<Get an identifier@>;
  713. @y
  714. "A".."Z","a".."z": @<Get an identifier@>;
  715. "$": scanning_hex:= true;
  716. @z
  717. ────────────────────────────────────────────────────────────────
  718. @x l.4805 m.267
  719. begin initialize; {beginning of the main program}
  720. @y
  721. @ @<Globals...@>=
  722. @!ExitSave: Pointer;
  723.  
  724. @ @p
  725. @={$F+}@>
  726. procedure FinishUp;
  727. @={$F-}@>
  728. begin
  729.   if ErrorAddr<>NIL then begin
  730.     write_ln('Internal error #',ExitCode);
  731.     ErrorAddr:= NIL;
  732.     Halt(ExitCode)
  733.   end;
  734. stat @<Print statistics about memory usage@>;@+tats@;@/
  735. @<Print the job |history|@>;
  736. @<Close all Files@>;
  737. ExitProc:= ExitSave;
  738. end; { FinishUp }
  739.  
  740. begin { main }
  741.   ExitSave:= ExitProc;
  742.   ExitProc:= @@FinishUp;
  743.  
  744.   if (ParamCount=0) then begin
  745.     print_ln(banner);
  746.     print_ln('Usage: WEAVE <WEB file> [<CHG file>]');
  747.     print_ln('');
  748.     Halt(history)
  749.   end;
  750.   initialize;
  751. @z
  752.  
  753. ────────────────────────────────────────────────────────────────
  754. @x l.4811 m.267
  755. end_of_WEAVE:
  756. stat @<Print statistics about memory usage@>;@+tats@;@/
  757. @t\4\4@>{here files should be closed if the operating system requires it}
  758. @<Print the job |history|@>;
  759. @y
  760. { exit via Unit WebExit (UNIT WebStuff) }
  761. @z
  762. ────────────────────────────────────────────────────────────────
  763. @x l.4847 m.270
  764. itself will get a new module number.
  765. @^system dependencies@>
  766. @y
  767. itself will get a new module number.
  768. @^system dependencies@>
  769.  
  770. Here we add the more extensive changes for this \.{TP} version
  771. of \.{WEAVE}.
  772.  
  773. @ The following function returns a commandline parameter without
  774.   an option
  775.  
  776. @<All purpose procedures and functions@>=
  777.    function Parameter (i: word): String;
  778.    var
  779.      p: word;
  780.      s: String;
  781.    begin
  782.      s:= ParamStr(i);
  783.      p:= pos('-',s);
  784.      if p=0 then p:= pos('/',s);
  785.      if p>0 then byte(s[0]):= p-1;
  786.      Parameter:= s
  787.    end;
  788.  
  789. @  temporary
  790. @<Typed constants...@>=
  791. octconv: boolean = false;
  792. @z
  793.